<template>
	
  <view class="uni-container">
    <uni-forms ref="form" :model="formData" validateTrigger="bind">
      <uni-forms-item name="name" label="名字">
        <uni-easyinput v-model="formData.name" placeholder="请输入发音人名字,如:小美"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item name="title" label="声音分类">
        <uni-easyinput v-model="formData.title" placeholder="请输入声音分类,如:中文普通话"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item name="avatar" label="头像">
        <uni-file-picker limit="1" @success="setFilePicker"></uni-file-picker>
      </uni-forms-item>
      <uni-forms-item name="scene" label="使用场景">
        <uni-easyinput v-model="formData.scene" placeholder="请输入引用场景,如对话数字人,通用场景"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item name="language" label="支持语言">
        <uni-easyinput v-model="formData.language" placeholder="请输入支持的语言,如:中文普通话,英文"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item name="same" label="采样率">
        <uni-easyinput v-model="formData.same" placeholder="请输入支持的采样率,如:16K,24K,48K"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item name="quality" label="音频品质">
        <uni-easyinput v-model="formData.quality" placeholder="请输入音频品质,如标准版,lite版,精品版"></uni-easyinput>
      </uni-forms-item>
	  
	  <uni-forms-item name="type" label="分类平台">
	    <uni-section title="本地数据" type="line">
	          <uni-data-select
	            v-model="formData.type"
	            :localdata="typeData"
	          ></uni-data-select>
	        </uni-section>
	  </uni-forms-item>
	  
     
      <uni-forms-item name="voice" label="关键词">
        <uni-easyinput v-model="formData.voice" placeholder="请输入提交给接口的关键词,如:xiaomei"></uni-easyinput>
      </uni-forms-item>
	  
	  <uni-forms-item name="audio_url" label="试听文本">
	    <uni-easyinput v-model="content" type="textarea" placeholder="请输入试听文本"></uni-easyinput>
	  </uni-forms-item>
	  
      <uni-forms-item name="audio_url" label="试听链接">
        <uni-easyinput v-model="formData.audio_url" type="textarea" placeholder="请输入试听链接地址" style="width:70%;float:left;"></uni-easyinput><button style="width:20%;float:left;height:36px;line-height:36px;margin-left:10px;background:#2979ff;color:#fff;font-size:13px;" @click="getTempAudioUrl()">生成链接</button>
      </uni-forms-item>
      <view class="uni-button-group">
        <button type="primary" class="uni-button" style="width: 100px;" @click="submit">提交</button>
        <navigator open-type="navigateBack" style="margin-left: 15px;">
          <button class="uni-button" style="width: 100px;">返回</button>
        </navigator>
      </view>
    </uni-forms>
  </view>
</template>
<style scoped>
	.popup-down-url button:first-child{background:#2979ff;color:#fff;margin-left:100px;}
	.popup-down-url button{width:30%;height:40px;line-height:40px;font-size:12px;float:left;margin-left:40px;}
	.popup-down-url{width:90%;margin-left:5%;line-height:30px;word-break: break-all;word-wrap: break-word;font-size:13px;margin-top:20px;}
	.popup-content{width:100%;height:250px;}
	.popup-title{width:calc(100% - 20px);height:30px;border-bottom:1px solid #eee;padding-left:20px;line-height:30px;font-size:13px;}
	.popup-box{width:800px;height:400px;background:#fff;border-radius: 10px;}
</style>
<script>
  import { validator } from '../../js_sdk/validator/timbre.js';

  const db = uniCloud.database();
  var aliyun = uniCloud.importObject('aliyun',{customUI:true});
  const dbCmd = db.command;
  const dbCollectionName = 'timbre';
  const appkey = 'j3scncIN1W0zDeio';
  import CryptoJS from 'crypto-js';
  function getValidator(fields) {
    let result = {}
    for (let key in validator) {
      if (fields.includes(key)) {
        result[key] = validator[key]
      }
    }
    return result
  }

  

  export default {
    data() {
      let formData = {
        "name": "",
        "title": "",
        "avatar": "",
        "scene": "",
        "language": "",
        "same": "",
        "quality": "",
        "use_number": 0,
        "voice": "",
        "audio_url": "",
		"type":""
      }
      return {
		  typeData:[
			  {
				  value:'baidu',
				  text:'百度云'
			  },
			  {
				  value:'aliyun',
				  text:'阿里云'
			  },
			  {
			  	  value:'cosyvoice',
			  	  text:'阿里云-CosyVoice'
			  }
		  ],
		  content:'把心情和脾气调成静音模式， 让我们低配生活，高配心灵，以欢喜之心，慢度日常。” 合什么群，合谁的群，和谁合群，在丑小鸭的世界里天鹅也有罪，不需要合群，做你自己就很好。',
        formData,
        formOptions: {},
		accessToken:{},//token
		resultStatus:{},//最终语音合成结果
        rules: {
          ...getValidator(Object.keys(formData))
        }
      }
    },
    onReady() {
	  this.checkAccessToken();
      this.$refs.form.setRules(this.rules)
    },
    methods: {
		//下载音频
		setDownLoad(url){
			var that = this;
			uni.downloadFile({
				url: url,
				timeout:500000,
				success: (res) => {
					
					if (res.statusCode === 200) {
						//上传到服务器
						var tempUrl = res.tempFilePath;
						uniCloud.uploadFile({
						        filePath: tempUrl,
						        cloudPath: that.uuid+'.mp3',
						        success(e) {
									that.formData.audio_url = e.fileID;
								},
						        fail(err) {
									console.log('上传错误',err);
								}
						      });
					}
				},
				fail(err) {
					uni.showToast({
						title:'配音失败',
						icon:'error',
						duration:2000
					})
				}
			});
		},
		//生成音频临时链接地址
		getTempAudioUrl(){
			var that = this;
			uni.showLoading({
				title:'配音中'
			})
			if(!that.formData.voice){
				uni.showToast({
					title:'请输入关键词',
					icon:'error',
					duration:2000
				})
				return false;
			};
			var data = {
				"payload":{
					"tts_request":{
						"voice":that.formData.voice,
						"sample_rate":48000,
						"format":"mp3",
						"text":that.content,
						"enable_subtitle": true,
						"volume":100,//音量
					},
					"enable_notify":false
				},
				"header":{
					"appkey":appkey,
					"token":that.accessToken.Id
				}
			};
			
			aliyun.getAudioTaskId(data).then(res=>{
				var taskId = res.result.data.task_id;
				if(taskId){
					that.getAudioResult(taskId);
				}else{
					uni.hideLoading()
					uni.showToast({
						title:'配音失败',
						icon:'error',
						duration:2000
					})
				}
			}).catch(err=>{
				uni.hideLoading()
				uni.showToast({
					title:'配音失败',
					icon:'error',
					duration:2000
				})
			})
			
		},
		//获取语音合成最终结果
		getAudioResult(taskId){
			var that = this;
			if(!taskId){
				uni.showToast({
					title:'配音失败',
					icon:'error',
					duration:2000
				})
				return;
			}
			var data = {
				appkey:appkey,
				token:that.accessToken.Id,
				task_id:taskId
			}
				var i = 0;
				var interval = setInterval(function(){
					if(that.resultStatus.error_message!='SUCCESS'){
						aliyun.getAudioTaskResult(data).then(res=>{
							that.resultStatus = res.result;
							if(res.result && res.result.data && res.result.data.audio_address){
								that.setDownLoad(res.result.data.audio_address);
							}
							
						})
					}else{
						uni.hideLoading();
						uni.showToast({
							title:'配音成功了'
						})
						clearInterval(interval);
					}
					i++;
				},1000);
				
			
			
			
		},
		//验证token是否过期
		checkAccessToken(){
			var that = this;
			var time = new Date().getTime()/1000;
			uni.getStorage({
				key:'aliyun-accessToken',
				success:function(result){
					var token = result.data;
					if(token && token.Id && time > token.ExpireTime){
						that.accessToken = token;
					}else{
						that.getAccessToken();
					}
				},
				fail:function(){
					that.getAccessToken();
				}
			})
			
		},
		//获取token
		getAccessToken(){
			var that = this;
			var timeStamp = that.timestampToDate();
			var tokenParam = {
				AccessKeyId:'LTAI5tFNLhLUszjxU5ZhmwJ8',
				Action:'CreateToken',
				Version:'2019-02-28',
				Format:'JSON',
				RegionId:'cn-shanghai',
				Timestamp:timeStamp,
				SignatureMethod:'HMAC-SHA1',
				SignatureVersion:'1.0',
				SignatureNonce:that.uuid()
				
			}
			//构造规范化的请求字符串
			var querySignString = that.sortAndConcatUrlParams(tokenParam);
			var stringToSign = 'GET&'+encodeURIComponent('/')+'&'+encodeURIComponent(querySignString);
			var accessKeySecret= '6pIOvefpppXl08B5b0Rd0ZJ7BpwLMZ';
			var signature = encodeURIComponent(that.hmacSHA1(stringToSign,accessKeySecret+'&'));
			querySignString = signature+'&'+querySignString;
			var url = 'http://nls-meta.cn-shanghai.aliyuncs.com/?Signature='+querySignString;
			uni.request({
				url:url,
				method:'GET',
				success:function(e){
					var token = e.data.Token;
					//将token缓存到本地
					uni.setStorage({
						key:'aliyun-accessToken',
						data:token,
						success:function(){
							that.accessToken = token;
						}
					})
				}
			})
		},
		hmacSHA1(message, secret) {
		  return CryptoJS.HmacSHA1(message, secret).toString(CryptoJS.enc.Base64);
		},
		//对参数key进行排序后再拼接为url参数字符串
		sortAndConcatUrlParams(params) {
		  const sortedKeys = Object.keys(params).sort(); // 对参数键进行排序
		  const sortedParams = sortedKeys.map(key => {
		    const encodedKey = encodeURIComponent(key);
		    const encodedValue = encodeURIComponent(params[key]);
		    return `${encodedKey}=${encodedValue}`;
		  });
		  return sortedParams.join('&'); // 使用&拼接参数
		},
		//将时间戳转化为固定格式的日期 
		timestampToDate() {
		  var now = new Date();
		     // 将当前本地时间转换为UTC时间
			var utc = new Date(now.getTime() - 28800000);
			// 获取UTC时间的时间戳
		  const year = utc.getFullYear(); // 获取年份
		  const month = ('0' + (utc.getMonth() + 1)).slice(-2); // 获取月份，转为两位数
		  const day = ('0' + utc.getDate()).slice(-2); // 获取日，转为两位数
		  const hours = ('0' + utc.getHours()).slice(-2); // 获取小时，转为两位数
		  const minutes = ('0' + utc.getMinutes()).slice(-2); // 获取分钟，转为两位数
		  const seconds = ('0' + utc.getSeconds()).slice(-2); // 获取秒钟，转为两位数
		 
		  // 拼接字符串
		  return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}Z`;
		},
		//UUID
		uuid() {
		  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
		    var r = Math.random() * 16 | 0,
		        v = c === 'x' ? r : (r & 0x3 | 0x8);
		    return v.toString(16);
		  });
		},
      //上传头像
	  setFilePicker(e){
		  var file = e.tempFilePaths[0];
		  this.formData.avatar = file;
	  },
      /**
       * 验证表单并提交
       */
      submit() {
        uni.showLoading({
          mask: true
        })
        this.$refs.form.validate().then((res) => {
          return this.submitForm(res)
        }).catch(() => {
        }).finally(() => {
          uni.hideLoading()
        })
      },

      /**
       * 提交表单
       */
      submitForm(value) {
        // 使用 clientDB 提交数据
        return db.collection(dbCollectionName).add(value).then((res) => {
          uni.showToast({
            title: '新增成功'
          })
          this.getOpenerEventChannel().emit('refreshData')
          setTimeout(() => uni.navigateBack(), 500)
        }).catch((err) => {
          uni.showModal({
            content: err.message || '请求服务失败',
            showCancel: false
          })
        })
      }
    }
  }
</script>
